home *** CD-ROM | disk | FTP | other *** search
- # (nowrap)
- # AlphaTcl - core Tcl engine
-
- namespace eval mode {}
- namespace eval win {}
- namespace eval menu {}
-
- # ◊◊◊◊ Declare Alpha packages ◊◊◊◊ #
-
- # This procedure is not yet final. Please do not rely on its API for
- # use outside of Alpha's core. Changes may be made to streamline Alpha's
- # package initialisation and declaration process.
- proc alpha::declare {what name version modes {initialise ""} {activate ""} {deactivate ""} args} {
- global alpha::rebuilding
- if {!${alpha::rebuilding}} {return}
- global index::feature rebuild_cmd_count index::flags
- if {[string trim "$initialise$activate$deactivate"] == ""} {
- set index::feature($name) [list $version $modes -1]
- } else {
- switch -- $what {
- "feature" {
- set init 0
- }
- "menu" {
- set init 1
- }
- "flag" {
- set init 2
- lappend index::flags $name
- }
- "autofeature" {
- set init 3
- }
- default {
- error "Bad alpha::declare type '$what'"
- }
- }
- set index::feature($name) [list $version $modes $init $initialise $activate $deactivate]
- }
- if {[llength $args]} {
- eval alpha::package [lindex $args 0] $name $version [lrange $args 1 end]
- return
- }
- if {[info exists rebuild_cmd_count] && [incr rebuild_cmd_count -1] == 0} {
- return -code 11
- }
- }
-
- proc alpha::feature {name version modes {initialise ""} {activate ""} {deactivate ""} args} {
- uplevel 1 [list alpha::declare feature $name $version $modes \
- $initialise $activate $deactivate] $args
- }
-
- proc alpha::flag {name version prefsPage modes args} {
- if {[string length $prefsPage]} {
- set init "set $name 0 ; lappend flagPrefs($prefsPage) $name"
- } else {
- set init "set $name 0"
- }
- uplevel 1 [list alpha::declare flag $name $version $modes \
- $init "set $name 1" "set $name 0"] $args
- }
-
- proc alpha::extension {name version {script ""} args} {
- uplevel 1 [list alpha::declare feature $name $version "global-only" "" $script ""] $args
- }
-
- proc alpha::menu {name version modes {value ""} {initialise ""} {activate ""} {deactivate ""} args} {
- global alpha::rebuilding
- if {!${alpha::rebuilding}} {
- # This is required when autoloading some procs without activating
- # a menu
- global $name
- ensureset $name $value
- return
- }
- if {[regexp {^•} [string index $modes 0]]} {
- # it's in the old format
- set tmp $modes
- set modes $value
- if {$modes == "in_menu"} { set modes "global" }
- set value $tmp
- # perhaps there's a better way of collapsing these arguments
- if {[llength $args]} {
- set args [concat [list $activate $deactivate] $args]
- } else {
- if {$deactivate != ""} {
- lappend activate $deactivate
- set args $activate
- } else {
- set args $activate
- }
- }
- set activate "$name"
- set deactivate ""
- }
- uplevel 1 [list alpha::declare menu $name $version $modes \
- "ensureset $name $value\n$initialise" $activate $deactivate] $args
- }
-
- proc alpha::mode {name version dummyProc {ext ""} {menus ""} {script ""} args} {
- global alpha::rebuilding alpha::requirements pkg_file
- if {!${alpha::rebuilding}} {return}
- namespace eval ::$name {}
- global index::mode rebuild_cmd_count index::oldmode
- if {$dummyProc == "source"} {
- # We could use 'info script' instead of pkg_file, except
- # for encoding purposes we might not be using 'source' to source files.
- set dummyProc [alpha::actionOnFileScript source $pkg_file]
- }
- # We need to convert the 'list' $ext into a real list in which
- # there are no newline, etc characters.
- set exts [list]
- foreach e $ext {
- lappend exts $e
- }
- if {[info exists index::mode($name)]} {
- dialog::alert "You have a duplicate definition of $name mode,\
- possibly in the file [info script]. This is likely to lead\
- to problems, in which this new definition partially or completely\
- overrides the original. You should remove one of the definitions."
- }
- set index::mode($name) [list $version $dummyProc $exts $menus $script]
- if {[info exists index::oldmode($name)]} {
- if {[set omenus [lindex [set index::oldmode($name)] 3]] != $menus} {
- global alpha::noMenusYet mode::features modifiedArrayElements
- if {![info exists mode::features($name)]} {set mode::features($name) ""}
- foreach m $menus {
- # Store all version number requirements
- if {[lindex $m 2] != ""} {
- lappend alpha::requirements [list $name $m]
- }
- set mm [lindex $m 0]
- if {([lsearch -exact $omenus $mm] == -1) \
- && ([lsearch -glob $omenus "$mm *"] == -1)} {
- # it's new
- package::addRelevantMode $mm $name
- if {[lindex $m 1] == 0} {continue}
- if {[info exists alpha::noMenusYet]} {
- # we added a feature
- hook::register startupHook "lunion mode::features($name) $mm"
- } else {
- lunion mode::features($name) $mm
- lappend modifiedArrayElements [list $name mode::features]
- }
- }
-
- }
- foreach om $omenus {
- set omm [lindex $om 0]
- if {([lsearch -exact $menus $omm] == -1) \
- && ([lsearch -glob $menus "$omm *"] == -1)} {
- # it has been removed from the default list
- package::removeRelevantMode $omm $name
- set mode::features($name) [lremove [set mode::features($name)] $omm]
- lappend modifiedArrayElements [list $name mode::features]
- }
- }
- }
- }
- if {[llength $args]} {
- eval alpha::package [lindex $args 0] $name $version [lrange $args 1 end]
- return
- }
- if {[info exists rebuild_cmd_count] && [incr rebuild_cmd_count -1] == 0} {
- return -code 11
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "addMode" -- you probably won't call this proc yourself
- #
- # -------------------------------------------------------------------------
- ##
- proc addMode {m dummy suffs _features} {
- global mode::features filepats dummyProc index::feature
- namespace eval ::$m {}
- if {[string length $dummy]} {set dummyProc($m) $dummy}
- ensureset mode::features($m) $_features
- foreach f $_features {
- package::addRelevantMode $f $m
- }
- ensureset filepats($m) $suffs
- }
-
- proc addMenu {name {val ""} {modes ""} {helpText ""}} {
- global menus index::feature index::help
- lunion menus $name
- if {$val != ""} {
- global $name
- if {![info exists $name]} { set $name $val }
- }
- if {[info exists index::feature($name)]} {
- eval lappend modes [lindex [set index::feature($name)] 1]
- }
- set index::feature($name) \
- [list [list "mode" [lindex $modes 0]] $modes 1 "" $name ""]
- set index::help($val) $helpText
- }
-
-
- # ◊◊◊◊ Procs Alpha calls directly ◊◊◊◊ #
- proc getModeValuesAlpha {} {
- global showInvisibles
-
- getWinInfo blah
- lappend m "Mac" [expr {$blah(platform) == "mac"}]
- lappend m "UNIX" [expr {$blah(platform) == "unix"}]
- lappend m "IBM" [expr {$blah(platform) == "ibm"}] {(-} 0
- lappend m "MPW" [expr {$blah(state) == "mpw"}]
- lappend m "Think" [expr {$blah(state) == "think"}]
- lappend m "None" [expr {$blah(state) == "none"}] {(-} 0
- lappend m "Read Only" $blah(read-only)
- lappend m "Show Invisibles" $showInvisibles {(-} 0
- lappend m "Tab Size" 0
- return $m
- }
-
-
- proc setModeVarAlpha {var} {
- global mode allFlags modeVars
- global ${mode}modeVars
-
- set var [string tolower $var]
- switch -- $var {
- "unix" -
- "mac" -
- "ibm" { setWinInfo platform $var ; setWinInfo dirty 1 }
- "mpw" -
- "think" -
- "none" { setWinInfo state $var }
- "tab size" {
- getWinInfo arr
- if {![catch {prompt "New tab size?" $arr(tabsize)} res]} {
- setWinInfo tabsize $res
- }
- }
- "read only" {
- getWinInfo b
- setWinInfo read-only [expr {-1 * ($b(read-only) - 1)}]}
- "show invisibles" {
- global showInvisibles
- set showInvisibles [expr {1 - $showInvisibles}]
- }
- }
- return
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "modes" --
- #
- # Called to get the list of modes for the modes popup
- # -------------------------------------------------------------------------
- ##
- proc modes {args} {
- return [mode::listAll]
- }
-
- # Called from alpha in response to the mode popup.
- proc newMode {newMode} {
- if {[package::helpOrDescribe $newMode]} { return }
- global win::Modes
- changeMode $newMode
- if {[catch {win::Current} name]} return
- set win::Modes($name) $newMode
- refresh
- }
-
- # ◊◊◊◊ Mode specific items ◊◊◊◊ #
-
- proc mode::listAll {} {
- global mode::features
- return [lsort -ignore [array names mode::features]]
- }
-
- proc mode::exists {m} {
- global mode::features
- info exists mode::features($m)
- }
-
- proc mode::removeFeatureFromAll {f} {
- global mode::features
- foreach m [array names mode::features] {
- if {[set idx [lsearch -exact [set mode::features($m)] $f]] >= 0} {
- set mode::features($m) [lreplace [set mode::features($m)] $idx $idx]
- prefs::modified mode::features($m)
- }
- }
- }
-
- proc mode::getFeatures {m} {
- global mode::features
- set mode::features($m)
- }
-
- proc mode::adjustFeatures {f {add 1}} {
- global mode::features mode
- set idx [lsearch -exact [set mode::features($mode)] $f]
- if {$add} {
- if {$idx < 0} {
- lappend mode::features($mode) $f
- package::activate $f
- prefs::modified mode::features($mode)
- }
- } else {
- if {$idx >= 0} {
- set mode::features($mode) [lreplace [set mode::features($mode)] $idx $idx]
- package::deactivate $f
- prefs::modified mode::features($mode)
- }
- }
- }
-
- proc mode::isFeatureActive {m f} {
- global mode::features
- return [expr {[lsearch -exact [set mode::features($m)] $f] != -1}]
- }
-
- proc mode::menuProc {menu item} {
- if {![llength [winNames -f]]} {
- alertnote "Mode operations require a current mode, and hence\
- a current window."
- return
- }
- switch -- $item {
- "preferences" dialog::modifyModeFlags
- "loadPrefsFile" mode::sourcePrefsFile
- "describeMode" mode::describe
- "changeMode" mode::changeDialog
- default {
- mode::$item
- }
- }
- }
-
-
- proc mode::changeDialog {} {
- global mode
- newMode [listpick -p "Mode:" -L $mode [mode::listAll]]
- }
-
- proc mode::describe {} {
- global mode ModeSuffixes mode::features
- global ${mode}modeVars
-
- set text "\r\tMODE $mode\r\r"
- if {![catch {package::describe $mode 1} res]} {
- append text $res "\r\r"
- }
-
- set tmp ""
- catch {set tmp [package::helpFile $mode 1]}
- append text "$tmp\r\r"
-
- set suffs ""
- foreach suf $ModeSuffixes {
- if {([llength $suf] == 3) && ([lindex $suf 1] == "winMode") \
- && ([lindex $suf 2] == $mode)} {
- lappend suffs $last
- }
- set last $suf
- }
- append text "Mode filepats: " [join $suffs ", "] "\r\r"
-
- append text "Mode menus and features: "
- if {[info exists mode::features($mode)]} {
- append text [join [set mode::features($mode)] ", "]
- }
- append text "\r\r"
- append text [mode::describeVars $mode]
-
- set etext "\rMode-independent bindings:\r"
- append text "\rMode-specific bindings:\r"
- foreach b [split [bindingList] "\r"] {
- set lst [lindex [split $b " "] end]
- if {$lst == $mode} {
- append text "\t$b\r"
- }
- }
- append text "\rTo list mode-independent bindings, select\
- 'List Global/All Bindings'\rfrom the Config menu.\r"
- new -n "* <$mode> MODE *" -m Tcl -text $text -shell 1 -read-only 1
- }
-
- proc mode::describeVars {pkg {pkgpref ""}} {
- cache::readContents index::prefshelp
- if {$pkgpref == ""} {set pkgpref $pkg}
- global ${pkgpref}modeVars
- append text "Package-specific variables:\r"
- if {[array exists ${pkgpref}modeVars]} {
- foreach v [lsort [array names ${pkgpref}modeVars]] {
- set val [set ${pkgpref}modeVars($v)]
- global flag::type
- set description ""
- if {[info exists prefshelp(${pkg},$v)]} {
- set description [dialog::helpdescription $prefshelp(${pkg},$v)]
- } elseif {[info exists prefshelp(${pkgpref},$v)]} {
- set description [dialog::helpdescription $prefshelp(${pkgpref},$v)]
- } elseif {[info exists prefshelp($v)]} {
- set description [dialog::helpdescription $prefshelp($v)]
- }
-
- if {$description != ""} {
- regsub -all "\[\r\n\]" [breakIntoLines $description] "& \# " description
- append text " # " $description "\r"
- }
- if {[info exists flag::type($v)] \
- && [regexp {binding$} [set flag::type($v)]]} {
- set val [dialog::specialView::binding $val]
- }
- append text [format " %-20s: \"%s\"\r" $v $val]
- }
- }
-
- return $text
- }
-
- # Now call the new proc dialog::pickMenusAndFeatures
-
- proc mode::menus {} {mode::menusAndFeatures 1}
- proc mode::features {} {mode::menusAndFeatures 2}
- proc mode::menusAndFeatures {{mfb 0}} {
- global mode
- dialog::pickMenusAndFeatures $mode $mfb
- }
-
- proc mode::getVar {var {aMode ""}} {
- global mode
- if {[string length $aMode] && ($aMode != $mode)} {
- # Use aMode, which is not current mode
- global ${aMode}modeVars
- if {[info exists ${aMode}modeVars($var)]} {
- return [set ${aMode}modeVars($var)]
- } else {
- global global::_varMem
- if {[info exists global::_varMem($var)]} {
- return [set global::_varMem($var)]
- } else {
- global $var
- return [set $var]
- }
- }
- } else {
- # use current mode
- global $var
- return [set $var]
- }
- }
-
- if {[info tclversion] < 8.0} {
- proc mode::proc {name args} {
- global mode
- if {[info commands ${mode}::$name] != ""} {
- eval ${mode}::$name $args
- } else {
- eval ::$name $args
- }
- }
- proc mode::getProc {name} {
- global mode
- if {[info commands ${mode}::$name] != ""} {
- return ${mode}::$name
- } else {
- return ""
- }
- }
-
- } else {
- proc mode::proc {name args} {
- global ::mode
- namespace eval ::$mode "$name $args"
- }
- proc mode::getProc {name} {
- global ::mode
- namespace eval ::$mode "namespace which $name"
- }
- }
-
- # Suffixes used to determine mode for new windows.
- proc mode::updateSuffixes {} {
- global ModeSuffixes filepats
-
- set ModeSuffixes [list default [list set winMode Text]]
- foreach m [mode::listAll] {
- if {[info exists filepats($m)]} {
- lappend ModeSuffixes $filepats($m) [list set winMode $m]
- }
- }
- }
-
- proc synchroniseModeVar {var args} {
- global mode $var
- if {[llength $args] > 0} {
- set $var [lindex $args 0]
- }
- global ${mode}modeVars modifiedArrayElements
- lappend modifiedArrayElements [list $var ${mode}modeVars]
- set ${mode}modeVars($var) [set $var]
- }
-
- # ◊◊◊◊ Miscellaneous ◊◊◊◊ #
-
- proc alpha::actionOnFileScript {action file} {
- global HOME
- if {[file::pathStartsWith $file $HOME suffix]} {
- append action " " "\[file join \"\$HOME\" \"$suffix\"\]"
- } else {
- lappend action $file
- }
- return $action
- }
-
- proc alpha::tryToLoad {msg args} {
- message "${msg}…"
- set i -1
- set ok 1
- while 1 {
- set do [lindex $args [incr i]]
- set say [lindex $args [incr i]]
- if {$say == ""} {
- set say "Loading $do"
- }
- if {$do == ""} {
- if {$ok} {
- message "${msg}…Complete."
- } else {
- alertnote "${msg}…Failed."
- }
- return $ok
- }
- message "${say}…"
- if {[catch $do err]} {
- if {[dialog::yesno -y "View the error" -n "Continue" \
- "$say failed!"]} {
- global errorInfo
- dialog::alert "$errorInfo"
- }
- }
- }
- }
-
- # ◊◊◊◊ Read in all the packages ◊◊◊◊ #
-
- proc alpha::findAllPlugins {} {
- # Execute pre-init code for each extension
- if {[cache::exists index::preinit]} {
- cache::readContents index::preinit
- foreach f [array names index::preinit] {
- set script [lindex [set index::preinit($f)] 1]
- try::level \#0 $script -reporting log -while "pre-initialising $f"
- }
- }
- # Now pull in regular initialisation
- alpha::findAllModes
- global skipPrefs
- if {!$skipPrefs} {
- alpha::findAllExtensions
- }
- }
-
- proc alpha::findAllModes {} {
- cache::readContents index::mode
- foreach f [array names index::mode] {
- eval addMode $f [lrange [set index::mode($f)] 1 3]
- if {[string length [set script [lindex [set index::mode($f)] 4]]]} {
- if {[catch {uplevel #0 $script} err]} {
- lappend problems "$f"
- }
- }
- }
- if {[info exists problems]} {
- alertnote "Problems loading modes: $problems"
- }
- mode::updateSuffixes
- }
-
-
-
-
-